parser grammar XMLParser;

options {
  language = Java;
  tokenVocab = XMLLexer;
  backtrack = true;
}


@header {
  package practpl.nuevemod;
}


@members {

    boolean cond_libro = false;
    boolean cond_autor = false;
    
    private ArrayList<RecognitionException> errors = new ArrayList<RecognitionException>();
    public ArrayList<RecognitionException> getErrors() {
       return errors;
    }
    @Override
    public void reportError (RecognitionException e) {
       String msg = getErrorMessage(e, getTokenNames());
       System.err.println(msg);
       errors.add(e);
    }
    
    boolean primera = true;
    String fecha_actual = "00000000";
    String nueva_fecha = "00000000";
    
    //Comprobamos si la nueva fecha que lee es menor que la actual
    boolean fechaMenor(String nueva_fecha) {
    
      boolean esMenor = false;
      
      if(primera) {
        fecha_actual = nueva_fecha;
        primera = false;
      }
      
      int i = nueva_fecha.length();
      while (i < fecha_actual.length()) {
        nueva_fecha += "0";
        i++;
      }

      Integer actual = Integer.parseInt(fecha_actual);    
      Integer nueva = Integer.parseInt(nueva_fecha);

      if (nueva <= actual) {
        esMenor = true;
        fecha_actual = nueva_fecha;
      }
      return esMenor;    
    }
    
}


@rulecatch {
catch (RecognitionException e) {
throw e;
}
}

//elementos : (elemento)*;
elementos : elemento;

elemento: a=apertura {if (a.compareTo("libro") == 0) {
                         cond_libro = true;
                         if(!fechaMenor(nueva_fecha)) {
                          System.err.println("ERROR: Los libros deben estar ordenados de forma descendente por la fecha");
                          throw new RecognitionException();
                         }
                         
                      }
                      else if (a.compareTo("autor") == 0) {
                         if (cond_libro)
                            cond_autor = true;
                         else {
                            System.err.println("ERROR: El tag: <" + a + "> se encuentra fuera de un libro.");
                            throw new RecognitionException();
                         }
                      }
                      }
//          elemento           
                        
          (elemento | IDENT)+

          c=cierre {if (a.compareTo(c) != 0) {
                       System.err.println("ERROR: El tag de apertura: <" + a + "> no coincide con el tag de cierre: </" + c + ">");
                       throw new RecognitionException();
                    }
                    
                    if (a.compareTo("libro") == 0) {
                       if (cond_libro && !cond_autor) {
                          System.err.println("ERROR: Debe incluirse el tag <autor> dentro del bloque libro.");
                          throw new RecognitionException();
                       }
                       cond_libro = false;
                       cond_autor = false;
                    }
                    }
            ;
//          |
//          ID+
//          |
//          COMENTARIO;
catch [RecognitionException ex] {throw ex;}


apertura returns [String id = ""]: ABRIR_ANGULO i=IDENT (IDENT IGUAL f=NUMERO {nueva_fecha = f.getText();})? 
                                   CERRAR_ANGULO {id += i.getText();} ;
                                                                                                    
cierre returns [String id = ""]: ABRIR_ANGULO_FIN i=IDENT ATRIBUTO? CERRAR_ANGULO {id += i.getText();};



